package com.example.androidencryption.utils;

import android.util.Log;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

/**
 * Android 支持的RSA加密方式
 * RSA/ECB/PKCS1Padding (1024, 2048)
 * RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
 * RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
 */
public class RSAUtils {
    private static final String TAG  = "RSAUtils";

    public static KeyPair genKeyPair() {
        try {
            KeyPairGenerator keyPairGen;
            keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(2048, new SecureRandom());
            return keyPairGen.generateKeyPair();

        } catch (Exception e) {
            Log.i(TAG, "genKeyPair error : " + e.getMessage());
        }
        return null;
    }

    public static PublicKey getPublicKey(KeyPair keyPair){
        return  keyPair.getPublic();
    }

    public static PrivateKey getPrivateKey(KeyPair keyPair){
        return  keyPair.getPrivate();
    }
   //=============================================Key 2 String==============
    public static  String getHexStrPublicKey(PublicKey publicKey){
        byte[] publicKeyEncoded = publicKey.getEncoded();
        return  ConvectionUtils.byte2HexStr(publicKeyEncoded);
    }

    public static  String getHexStrPrivateKey(PrivateKey privateKey){
        byte[] privateKeyEncoded = privateKey.getEncoded();
        return  ConvectionUtils.byte2HexStr(privateKeyEncoded);
    }

    //=============================================String 2 Key==============


    public static PublicKey loadPublicKey(String publicKeyStr) {
        try {
            byte[] buffer = ConvectionUtils.hexStr2Bytes(publicKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return keyFactory.generatePublic(keySpec);
        } catch (Exception e) {
            Log.i(TAG, "loadPublicKey error : " + e.getMessage());
        }

        return null;
    }


    public static PrivateKey loadPrivateKey(String privateKeyStr) {
        try {
            byte[] buffer =ConvectionUtils.hexStr2Bytes(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
           return keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            Log.i(TAG, "loadPrivateKey error : " + e.getMessage());
        }

        return null;
    }


    public static byte[] encrypt(PublicKey publicKey, byte[] plainTextData) {
        if (publicKey == null || plainTextData == null) {
            return null;
        }
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return cipher.doFinal(plainTextData);
        } catch (Exception e) {
            Log.i(TAG, "encrypt error : " + e.getMessage());
        }
        return null;
    }



    public static byte[] decrypt(PrivateKey privateKey, byte[] cipherData) {
        if (privateKey == null || cipherData == null) {
            return null;
        }
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return cipher.doFinal(cipherData);
        } catch (Exception e) {
            Log.i(TAG, "decrypt error : " + e.getMessage());
        }

        return null;
    }


}
